package com.ctgu.computer.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ctgu.computer.common.CommonConstants;
import com.ctgu.computer.common.UserLocalTread;
import com.ctgu.computer.domain.dto.TopicAddDTO;
import com.ctgu.computer.domain.dto.TopicPageDTO;
import com.ctgu.computer.domain.po.*;
import com.ctgu.computer.domain.result.PageResult;
import com.ctgu.computer.domain.vo.ImagePaths;
import com.ctgu.computer.domain.vo.TopicVO;
import com.ctgu.computer.exception.BaseException;
import com.ctgu.computer.mapper.TopicMapper;
import com.ctgu.computer.mapper.UserMapper;
import com.ctgu.computer.schedule.ScheduleTask;
import com.ctgu.computer.service.TopicService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.RequiredArgsConstructor;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;


@Service
@RequiredArgsConstructor
public class TopicServeImpl implements TopicService {

    private final TopicMapper topicMapper;
    private final UserMapper userMapper;
    private final FileStorageService fileStorageService;
    @Override
    public PageResult page(TopicPageDTO topicPageDTO) {
        PageHelper.startPage(topicPageDTO.getPageIndex(),topicPageDTO.getPageSize());
        Page<TopicVO> res = topicMapper.page(topicPageDTO);
        // 获取相关文章与用户的对应关系
        List<Integer> textIds = res.stream().map(TopicVO::getTextId).collect(Collectors.toList());
        Map<Integer,SenderTextInfo> senderTextInfoMap = topicMapper.batchSelectSenderToTextByTextId(textIds);
        List<Integer> senderIds = senderTextInfoMap.values().stream().map(SenderTextInfo::getSenderId).toList();
        // 获取用户Id与用户名映射
        Map<Integer, UserInfo> userInfoMap = userMapper.selectUserNameByIds(senderIds);
        UserIdToTextIds userIdToTextIds = new UserIdToTextIds(UserLocalTread.getUserId(),textIds);
        // 获取当前用户点赞过的文章id
        List<Integer> goodTextIds = topicMapper.selectGoodTextBy(userIdToTextIds);
        if(goodTextIds==null){
            goodTextIds=new ArrayList<>();
        }
        List<Integer> finalGoodTextIds = goodTextIds;
        res.forEach(topicVO -> {
//              String jsonString = topicVO.getCoverImage().toString();
//              List<String> coverImageArray = JSONObject.parseArray(jsonString, String.class);
//              topicVO.setCoverImage(coverImageArray);
                topicVO.setIdentity(senderTextInfoMap.get(topicVO.getTextId()).getIdentity());
                topicVO.setSenderUserName(userInfoMap.
                        get(senderTextInfoMap.
                                get(topicVO.getTextId()).
                                getSenderId()).
                        getUserName());
                topicVO.setSenderId(senderTextInfoMap.
                                get(topicVO.getTextId()).
                                getSenderId());
                topicVO.setIsGood(finalGoodTextIds.contains(topicVO.getTextId()));
        });
        return new PageResult(res.getTotal(),res.getResult());
    }

    @Override
    @Transactional
    public void addTopic(TopicAddDTO topicAddDTO) {
        Integer userId,identity;
        // 判断当前用户身份
        if(UserLocalTread.getUserId()!=null){
            userId = UserLocalTread.getUserId();
            identity = CommonConstants.USER;
        }else{
            userId =  UserLocalTread.getAdminId();
            identity = CommonConstants.ADMIN;
        }
        TextInfo textInfo = new TextInfo();
        BeanUtils.copyProperties(topicAddDTO,textInfo);
/*        MultipartFile[] files = topicAddDTO.getFiles();
        if (files != null && files.length>0){
            // 存放上传的文件路径
            List<String> image_Paths = new ArrayList<>();
            for (MultipartFile file : files) {
                if(!file.isEmpty()){
                    FileInfo upload = fileStorageService.of(file)
                            .setSaveFilename(userId +'-'+ UUID.randomUUID().toString()+".png")
                            .upload();
                    image_Paths.add(upload.getUrl());
                }
            }
            textInfo.setCoverImage(JSONObject.toJSONString(image_Paths));
        }*/
        topicMapper.insert(textInfo);
        SenderTextInfo senderTextInfo = SenderTextInfo.builder()
                .textId(textInfo.getTextId())
                .senderId(userId)
                .identity(identity)
                .build();
        topicMapper.insertSenderToTopic(senderTextInfo);
    }

    @Override
    public void addChannel(String channelName) {
        topicMapper.insertChannel(channelName);
    }

    @Override
    @Transactional
    public void deleteText(Integer textId) {
        SenderTextInfo senderTextInfo =  topicMapper.selectTextToSenderByTextId(textId);
        // 判断当前用户是否为文章发布者或者管理员
        if(!senderTextInfo.getSenderId().equals(UserLocalTread.getUserId())&&UserLocalTread.getAdminId()==null){
            throw new BaseException(CommonConstants.NOT_MAPPING_USER);
        }
        // 将文章id先缓存下来，用于后续删除相关的评论
        ScheduleTask.taskIds.add(textId);
        TextInfo textInfo = topicMapper.selectById(textId);
        List<String> imagePaths = JSONObject.parseArray(textInfo.getCoverImage().toString(), String.class);
        // 将删除文章所包含的文件路径缓存
        ScheduleTask.imagePaths.addAll(imagePaths);
        topicMapper.deleteByTextId(textId);
        topicMapper.deleteSenderToText(textId);
        topicMapper.deleteSenderToTextToComment(textId);
    }

    @Override
    public List<ChannelInfo> getAllChannel() {
        return topicMapper.getAllChannel();
    }

    @Override
    public TopicVO getById(Integer textId) {
        SenderTextInfo senderTextInfo =  topicMapper.selectTextToSenderByTextId(textId);
        TextInfo textInfo = topicMapper.selectById(textId);
        ChannelInfo channelInfo = topicMapper.selectChannelById(textInfo.getChannelId());
        String senderUserName = userMapper.selectUserInfoById(senderTextInfo.getSenderId()).getUserName();
        if(ScheduleTask.textIdReadCount.containsKey(textId)){
          ScheduleTask.textIdReadCount.replace(textId,ScheduleTask.textIdReadCount.get(textId)+1);
        }else{
            ScheduleTask.textIdReadCount.put(textId,textInfo.getReadCount()+1);
        }

        TopicVO topicVO = new TopicVO();
        BeanUtils.copyProperties(textInfo,topicVO);
        topicVO.setSenderId(senderTextInfo.getSenderId());
        topicVO.setSenderUserName(senderUserName);
        topicVO.setIdentity(senderTextInfo.getIdentity());
        topicVO.setChannelName(channelInfo.getChannelName());
        return topicVO;
    }

    @Override
    @Transactional
    public void good(Integer textId) {
        // 先查看用户是否点赞过
        GoodText existedGoodText = topicMapper.selectGoodTextByTextId(textId, UserLocalTread.getUserId());
        TextInfo textInfo = topicMapper.selectById(textId);
        if(existedGoodText==null){
            GoodText goodText = GoodText.builder()
                    .gooderId(UserLocalTread.getUserId())
                    .textId(textId)
                    .isGood(true)
                    .build();
            topicMapper.insertGoodText(goodText);
            topicMapper.update(TextInfo.builder()
                    .goodCount(textInfo.getGoodCount()+1)
                    .textId(textInfo.getTextId())
                    .build());
            return;
        }
        // 点赞后再次操作即为取消点赞
        if(existedGoodText.getIsGood()){
            existedGoodText.setIsGood(false);
            topicMapper.updateGood(existedGoodText);
            topicMapper.update(TextInfo.builder()
                    .goodCount(textInfo.getGoodCount()-1)
                    .textId(textInfo.getTextId())
                    .build());
        }else{
            existedGoodText.setIsGood(true);
            topicMapper.updateGood(existedGoodText);
            topicMapper.update(TextInfo.builder()
                    .goodCount(textInfo.getGoodCount()+1)
                    .textId(textInfo.getTextId())
                    .build());
        }

    }

    @Override
    public ImagePaths addImages(MultipartFile[] files) {
        List<String> paths = new ArrayList<>();
        for (MultipartFile file : files) {
            if(!file.isEmpty()){
                FileInfo upload = fileStorageService.of(file)
                        .setSaveFilename("topic-" +UserLocalTread.getUserId() + UUID.randomUUID() + ".png")
                        .upload();
                paths.add(upload.getUrl());
            }
        }
        return new ImagePaths(paths);
    }
}
